/*MyPhotoIndex Free Photo Organizer <www.myphotoindex.com>
  Copyright (C) <2006-2008>  <Asaf Yarkoni asaf@myphotoindex.com>

  This program is free software: you can redistribute it and/or modify
  it under the terms of the GNU General Public License as published by
  the Free Software Foundation, either version 3 of the License, or
  (at your option) any later version.

  This program is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU General Public License for more details.

  You should have received a copy of the GNU General Public License
  along with this program.  If not, see <http://www.gnu.org/licenses/>.*/

#pragma once
#pragma warning (disable : 4305)

#include "string.h"

using namespace System;
using namespace System::Drawing;
using namespace System::Drawing::Drawing2D;
using namespace System::Threading;
using namespace System::Collections::Generic;
using namespace System::Runtime::InteropServices;
using namespace MyPhotoIndex::Interfaces;

namespace MyPhotoIndex{namespace Plugins{namespace ImageFormatProviders 
{
	ref class Lock 
	{
	public:
	   Lock( Object ^ object ) : m_object( object ) 
	   {
		  Monitor::Enter( m_object );
	   }
	   ~Lock() 
	   {
		  Monitor::Exit( m_object );
	   }

	private:
		 Object^ m_object;
	};


	ref class Using 
	{
	public:
	   Using( IDisposable ^ object ) : m_object( object ) 
	   {
		 
	   }
	   ~Using() 
	   {
		  delete m_object;
	   }

	private:
		 IDisposable^ m_object;
	};

	ref class Args
	{
	public:
		Args():
		m_argv(nullptr)
		{
			m_args = gcnew List<String^>();
		}

		~Args()
		{
			this->!Args();
		}

		!Args()
		{
			ReleaseVars();
		}

		void Add (String^ value)
		{
			m_args->Add(value);
		}


		operator char**()
		{
			if (m_argv)
			{
				ReleaseVars();
			}

			int numOfVars = m_args->Count + 2;
			m_argv = new char*[numOfVars];

//first arg is allways empty
			m_argv[0] = new char[256];
			m_argv[0][0] = 0;

			int ii = 1;
			for each (String^ value in m_args)
			{
				m_argv[ii] = new char[256];

				char* tmpStr = (char*)(void*)Marshal::StringToHGlobalAnsi(value);
				strcpy(m_argv[ii++], tmpStr);
				Marshal::FreeHGlobal((IntPtr)tmpStr);
			}
			m_argv[ii] = nullptr; 
			
			return m_argv;
		}

		property int Count
		{
			int get()
			{
				return m_args->Count + 1;//add the first empty arg to the Count;
			}
		}

private:
		List<String^>^	m_args;
		char**			m_argv;

		void ReleaseVars()
		{
			int numOfVars = m_args->Count + 1;
			for(int ii = 0; ii < numOfVars; ii++)
			{
				delete[] m_argv[ii];
			}

			delete m_argv;
			m_argv = nullptr;
		}
	};

}}}